<template>
  <div ref="canvasContainer" class="canvas-container">
    <button class="btn-fullscreen" @click="onFullscreen">
      {{ isFullscreen ? '退出全屏' : '点击全屏' }}
    </button>
  </div>
</template>

<script setup>
import { onMounted, onUnmounted, ref } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

// 参考THREE.js库的WebGL渲染器的画布容器
const canvasContainer = ref(null)
// 点击全屏
const onFullscreen = () => {
  // 判断是否全屏
  if (document.fullscreenElement) {
    document.exitFullscreen()
  } else {
    canvasContainer.value.requestFullscreen()
  }
}
// 全屏状态
const isFullscreen = ref(false)

// 全屏事件监听
const handleFullscreenChange = () => {
  // 更新全屏状态
  isFullscreen.value = !!document.fullscreenElement
}
// 键盘事件监听
const handleKeydownChange = (e) => {
  if (e.key === "F11") {
    // 阻止默认全屏事件
    e.preventDefault()
    // 调用全屏方法
    onFullscreen()
  }
}

onMounted(() => {
  // 监听全屏事件
  document.addEventListener('fullscreenchange', handleFullscreenChange)

  // 监听键盘事件
  document.addEventListener('keydown', (e) => handleKeydownChange(e))

  // 创建一个新场景
  const scene = new THREE.Scene()

  // 创建一个透视相机，并设置其位置
  const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
  camera.position.z = 5

  // 创建一个立方体
  const geometry = new THREE.BoxGeometry(1, 1, 1)

  // 创建一个材质
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
  // 创建一个父级材质
  const parentMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff0000 })
  // 创建一个网格
  const cube = new THREE.Mesh(geometry, material)
  // 创建一个父级网格
  const parentCube = new THREE.Mesh(geometry, parentMaterial)
  // 将子级网格添加到父级网格中
  parentCube.add(cube)
  // 设置父级网格位置
  parentCube.position.set(-2, 0, 0)
  // 设置父级网格旋转
  parentCube.rotation.x = Math.PI / 4
  // 设置父级网格缩放
  // parentCube.scale.set(2, 2, 2)
  // 设置子级网格位置
  cube.position.set(2, 0, 0)
  // 设置子级网格旋转
  cube.rotation.x = Math.PI / 4
  // 设置子级网格缩放
  cube.scale.set(2, 2, 2)
  // 将父级网格添加到场景中
  scene.add(parentCube)

  // 创建一个WebGL渲染器，并设置其大小
  const renderer = new THREE.WebGLRenderer()
  renderer.setSize(window.innerWidth, window.innerHeight)

  // 将渲染器的画布元素添加到canvasContainer中
  canvasContainer.value.appendChild(renderer.domElement)

  // 添加一个坐标轴辅助对象到场景中，用于可视化坐标轴
  const axesHelper = new THREE.AxesHelper(5)
  scene.add(axesHelper)

  // 添加控制器
  const controls = new OrbitControls(camera, renderer.domElement)
  // 开启自动旋转
  // controls.autoRotate = true
  // 添加阻尼，使控制器更真实
  controls.enableDamping = true
  // 添加阻尼惯性
  controls.dampingFactor = 0.8

  // 开启渲染循环
  let isRendering = true
  const animate = () => {
    if (isRendering) {
      requestAnimationFrame(animate)
      // cube.rotation.x += 0.01
      // cube.rotation.y += 0.01
      controls.update()
      renderer.render(scene, camera)
    }
  }
  animate()
  // 监听窗口大小变化，并更新渲染器的大小
  window.addEventListener('resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
  })

  // 在组件卸载时停止渲染循环
  // 清理函数，当组件卸载时停止渲染循环
  onUnmounted(() => {
    isRendering = false
    document.removeEventListener('fullscreenchange', handleFullscreenChange)
    document.removeEventListener('keydown', handleKeydownChange)
  })
});

</script>

<style>
.canvas-container {
  width: 100%;
  height: 100%;
}

.btn-fullscreen {
  position: absolute;
  top: 10;
  left: 10;
  background-color: #fff;
  z-index: 999;
}
</style>